<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Concurrent Overview | YiChangKong For Blog</title><meta name="keywords" content="技术概述"><meta name="author" content="伊长空"><meta name="copyright" content="伊长空"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><meta name="description" content="并发包概述 提前话： 进行myCat摸索时到处可见的并发包的原子性数据操作，与其摸瞎子过河，不如先把瞎子摸一遍！！！🤔 于是便有了下面这片的技术博客（关于concurrent概述）🤨  Overview of the java.util.concurrent（概述）原文网址 Main Components（主要构成）The java.util.concurrent contains way">
<meta property="og:type" content="article">
<meta property="og:title" content="Concurrent Overview">
<meta property="og:url" content="https://yichangkong.gitee.io/2020/05/29/Concurrent%20Overview/index.html">
<meta property="og:site_name" content="YiChangKong For Blog">
<meta property="og:description" content="并发包概述 提前话： 进行myCat摸索时到处可见的并发包的原子性数据操作，与其摸瞎子过河，不如先把瞎子摸一遍！！！🤔 于是便有了下面这片的技术博客（关于concurrent概述）🤨  Overview of the java.util.concurrent（概述）原文网址 Main Components（主要构成）The java.util.concurrent contains way">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg">
<meta property="article:published_time" content="2020-05-29T08:34:58.000Z">
<meta property="article:modified_time" content="2020-11-23T11:12:49.946Z">
<meta property="article:author" content="伊长空">
<meta property="article:tag" content="技术概述">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://yichangkong.gitee.io/2020/05/29/Concurrent%20Overview/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css"><script>var GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  ClickShowText: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  justifiedGallery: {
    js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
    css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isanchor: false
};

var saveToLocal = {
  set: function setWithExpiry(key, value, ttl) {
    const now = new Date()
    const expiryDay = ttl * 86400000
    const item = {
      value: value,
      expiry: now.getTime() + expiryDay,
    }
    localStorage.setItem(key, JSON.stringify(item))
  },

  get: function getWithExpiry(key) {
    const itemStr = localStorage.getItem(key)

    if (!itemStr) {
      return undefined
    }
    const item = JSON.parse(itemStr)
    const now = new Date()

    if (now.getTime() > item.expiry) {
      localStorage.removeItem(key)
      return undefined
    }
    return item.value
  }
}</script><script id="config_change">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2020-11-23 19:12:49'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(function () {  window.activateDarkMode = function () {
    document.documentElement.setAttribute('data-theme', 'dark')
    if (document.querySelector('meta[name="theme-color"]') !== null) {
      document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
    }
  }
  window.activateLightMode = function () {
    document.documentElement.setAttribute('data-theme', 'light')
   if (document.querySelector('meta[name="theme-color"]') !== null) {
      document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
    }
  }
  const autoChangeMode = 'false'
  const t = saveToLocal.get('theme')
  if (autoChangeMode === '1') {
    const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
    const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
    const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
    const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified
    if (t === undefined) {
      if (isLightMode) activateLightMode()
      else if (isDarkMode) activateDarkMode()
      else if (isNotSpecified || hasNoSupport) {
        const now = new Date()
        const hour = now.getHours()
        const isNight = hour <= 6 || hour >= 18
        isNight ? activateDarkMode() : activateLightMode()
      }
      window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
        if (saveToLocal.get('theme') === undefined) {
          e.matches ? activateDarkMode() : activateLightMode()
        }
      })
    } else if (t === 'light') activateLightMode()
    else activateDarkMode()
  } else if (autoChangeMode === '2') {
    const now = new Date()
    const hour = now.getHours()
    const isNight = hour <= 6 || hour >= 18
    if (t === undefined) isNight ? activateDarkMode() : activateLightMode()
    else if (t === 'light') activateLightMode()
    else activateDarkMode()
  } else {
    if (t === 'dark') activateDarkMode()
    else if (t === 'light') activateLightMode()
  }const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
   if (asideStatus === 'hide') {
     document.documentElement.classList.add('hide-aside')
   } else {
     document.documentElement.classList.remove('hide-aside')
   }
}})()</script><meta name="generator" content="Hexo 5.2.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="author-avatar"><img class="avatar-img" src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20200417183933.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">45</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">9</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">45</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> Archives</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> Link</span></a></div></div></div></div><div id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url(https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg)"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">YiChangKong For Blog</a></span><span id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> Archives</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> Link</span></a></div></div><span class="close" id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></span></span></nav><div id="post-info"><h1 class="post-title">Concurrent Overview</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-05-29T08:34:58.000Z" title="发表于 2020-05-29 16:34:58">2020-05-29</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2020-11-23T11:12:49.946Z" title="更新于 2020-11-23 19:12:49">2020-11-23</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/">Java</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/%E9%AB%98%E5%B9%B6%E5%8F%91%E4%B8%8E%E5%A4%9A%E7%BA%BF%E7%A8%8B/">高并发与多线程</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/%E9%AB%98%E5%B9%B6%E5%8F%91%E4%B8%8E%E5%A4%9A%E7%BA%BF%E7%A8%8B/Concurrent/">Concurrent</a></span></div><div class="meta-secondline"> <span class="post-meta-separator">|</span><span class="post-meta-pv-cv"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><p> 并发包概述</p>
<h1 id="提前话："><a href="#提前话：" class="headerlink" title="提前话："></a>提前话：</h1><blockquote>
<p><strong>进行myCat摸索时到处可见的并发包的原子性数据操作，与其摸瞎子过河，不如先把瞎子摸一遍！！！🤔 于是便有了下面这片的技术博客（关于concurrent概述）🤨</strong></p>
</blockquote>
<h1 id="Overview-of-the-java-util-concurrent（概述）"><a href="#Overview-of-the-java-util-concurrent（概述）" class="headerlink" title="Overview of the java.util.concurrent（概述）"></a>Overview of the java.util.concurrent（概述）</h1><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-util-concurrent#1-executor">原文网址</a></p>
<h2 id="Main-Components（主要构成）"><a href="#Main-Components（主要构成）" class="headerlink" title="Main Components（主要构成）"></a><strong>Main Components</strong>（主要构成）</h2><p>The <em>java.util.concurrent</em> contains way too many features to discuss in a single write-up. In this article, we will mainly focus on some of the most useful utilities from this package like:（在这片文章中如果一次撰写或讨论concurrent的功能、方式会太多，所以我们将大部分的精力集中于最常使用的实用程序）</p>
<ul>
<li><em>Executor</em>（执行者）</li>
<li><em>ExecutorService</em>（执行器服务）</li>
<li><em>ScheduledExecutorService</em>（执行器服务时间表）</li>
<li><em>Future</em>（）</li>
<li><em>CountDownLatch</em>（倒计时）</li>
<li><em>CyclicBarrier</em>(循环屏障？？)</li>
<li><em>Semaphore</em></li>
<li><em>ThreadFactory</em></li>
<li><em>BlockingQueue</em></li>
<li><em>DelayQueue</em></li>
<li><em>Locks</em></li>
<li><em>Phaser</em></li>
</ul>
<p>You can also find many dedicated articles to individual classes here.</p>
<h3 id="Executor-执行器"><a href="#Executor-执行器" class="headerlink" title="Executor(执行器)"></a><strong>Executor</strong>(执行器)</h3><blockquote>
<p><strong><em><a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html">Executor</a>\</em> is an interface that represents an object that executes provided tasks.</strong></p>
<p>（Executor 是一个代表执行提供任务的一个接口对象）</p>
<p>It depends on the particular implementation (from where the invocation is initiated) if the task should be</p>
<p>它依赖于一个特定的实现（从启动调用的位置）如果这个任务需要运行在一个新线程或者当前线程</p>
<p>run on a new or current thread. Hence, using this interface, we can decouple the task execution flow from</p>
<p>因此，使用这个接口 我们可以将任务执行流与实际任务执行机制进行解耦（decouple）。</p>
<p>the actual task execution mechanism.</p>
<p>One point to note here is that <em>Executor</em> does not strictly require the task execution to be asynchronous.</p>
<p>这里需要注意的一点是，执行器并不严格要求任务执行是异步的。</p>
<p>In the simplest case, an executor can invoke the submitted task instantly in the invoking thread.</p>
<p>在这个简单的例子上， 执行者可以在调用线程中立即（instantly 即刻）调用提交的任务。</p>
<p>We need to create an invoker to create the executor instance:</p>
<p>我们需要生成一个调用者去生成一个执行者实例</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">public class MyExecutor &#123;</span><br><span class="line">  public static void main(String[] args) &#123;</span><br><span class="line">    System.out.println(&quot;Begin execute&quot;);</span><br><span class="line">    execute();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  public static void execute() &#123;</span><br><span class="line">    Executor executor &#x3D; new Invoker();</span><br><span class="line">    executor.execute(</span><br><span class="line">        () -&gt; &#123; &#x2F;&#x2F; task to be performed 准备执行任务</span><br><span class="line">          System.out.println(&quot;Hello Executor&quot;);</span><br><span class="line">        &#125;);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class Invoker implements Executor &#123;</span><br><span class="line">  &#x2F;&#x2F; We need to create an invoker to create the executor instance:</span><br><span class="line">  &#x2F;&#x2F; 我们需要创建一个调用程序来创建执行程序实例：</span><br><span class="line">  @Override</span><br><span class="line">  public void execute(Runnable runnable) &#123;</span><br><span class="line">    runnable.run();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><em>看到上述的案例，想必你想问，那我直接print（“Hello Executor”）不行吗？？？（其实可以作为executor的生成案例） 我也正疑惑呢 so 得找个好案例</em></p>
<p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://gitee.com/yichangkong/JavaBasis/tree/master/src/Concurrent/Executor">Executor</a></p>
</blockquote>
<h3 id="ExecutorService（执行器服务）"><a href="#ExecutorService（执行器服务）" class="headerlink" title="ExecutorService（执行器服务）"></a><strong>ExecutorService</strong>（执行器服务）</h3><blockquote>
<p><em>ExecutorService</em> is a complete solution for asynchronous processing.(执行器服务是异步进程的一个完整解决方案) It manages an in-memory queue and schedules submitted tasks based on thread availability.</p>
<p>它管理着内存中的队列（什么队列？？？🤔 🤨）并根据线程可用性安排已提交的任务。</p>
<p>To use <em>ExecutorService,</em> we need to create one <em>Runnable</em> class.</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">public class Task implements Runnable &#123;</span><br><span class="line">    @Override</span><br><span class="line">    public void run() &#123;</span><br><span class="line">        &#x2F;&#x2F; task details</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Now we can create the <em>ExecutorService</em> instance and assign this task. At the time of creation,</p>
<p>下面我们开始生成一个ExecutorService 实例并且分配一些任务，在生成的时候，我们需要指定线程池的大小</p>
<p>we need to specify the thread-pool size.</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ExecutorService executor &#x3D; Executors.newFixedThreadPool(10);</span><br></pre></td></tr></table></figure>

<p>If we want to create a single-threaded <em>ExecutorService</em> instance, we can use</p>
<p>如果我们想创建一个单线程的执行器服务实例，我们可以使用（）去生成一个实例</p>
<p><strong><em>newSingleThreadExecutor(ThreadFactory threadFactory)\</em></strong> to create the instance.</p>
<p>Once the executor is created, we can use it to submit the task.</p>
<p>一旦这个执行者被生成，我们就可以使用它去提交任务</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public void execute() &#123; </span><br><span class="line">    executor.submit(new Task()); </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>We can also create the <em>Runnable</em> instance while submitting the task.</p>
<p>我们还可以在提交任务时创建Runnable实例。</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">executor.submit(() -&gt; &#123;</span><br><span class="line">    new Task();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>It also comes with two out-of-the-box execution termination methods.</p>
<p>它也有两种现成（out of the box）的执行终止方法</p>
<p>The first one is <em>shutdown()</em>; it waits until all the submitted tasks finish executing.</p>
<p>等待所有的提交任务执行完毕</p>
<p>The other method is <em>shutdownNow()</em> whic<em>h</em> immediately terminates all the pending/executing tasks.</p>
<p>该方法立即终止（terminates）所有待处理/正在执行的任务。</p>
<p>There is also another method <em>awaitTermination(long timeout, TimeUnit unit)</em></p>
<p>which forcefully blocks until all tasks have completed execution after a shutdown event triggered</p>
<p>or execution-timeout occurred,</p>
<p>在触发关闭事件或发生执行超时后或者这个执行线程本身中断，它会强制阻塞直到所有任务都已完成执行，</p>
<p>or the execution thread itself is interrupted（中断）,</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">try &#123;</span><br><span class="line">    executor.awaitTermination( 20l, TimeUnit.NANOSECONDS );</span><br><span class="line">&#125; catch (InterruptedException e) &#123;</span><br><span class="line">    e.printStackTrace();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个executorService还是有点懵逼🤬</p>
</blockquote>
<h3 id="ScheduledExecutorService（定时调度机制）"><a href="#ScheduledExecutorService（定时调度机制）" class="headerlink" title="ScheduledExecutorService（定时调度机制）"></a><strong>ScheduledExecutorService（定时调度机制）</strong></h3><blockquote>
<p><em>ScheduledExecutorService</em> is a similar interface to <em>ExecutorService,</em> but it can perform tasks periodically.</p>
<p>xxx是类似于执行器服务的一个接口，但是它可定期执行任务，So you know that</p>
<p><strong><em>Executor and ExecutorService\</em>‘s methods are scheduled on the spot without introducing any artificial delay.</strong></p>
<p>XXX的方法是立即运行 没有引入任何人为的延迟</p>
<p>Zero or any negative value signifies that the request needs to be executed instantly.</p>
<p>零和任何负值都表示这个请求需要立即执行</p>
<p>We can use both <em>Runnable</em> and <em>Callable</em> interface to define the task.</p>
<p>define 定义</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">public void execute() &#123;</span><br><span class="line">    ScheduledExecutorService executorService</span><br><span class="line">      &#x3D; Executors.newSingleThreadScheduledExecutor();</span><br><span class="line"> </span><br><span class="line">    Future&lt;String&gt; future &#x3D; executorService.schedule(() -&gt; &#123;</span><br><span class="line">        &#x2F;&#x2F; ...</span><br><span class="line">        return &quot;Hello world&quot;;</span><br><span class="line">    &#125;, 1, TimeUnit.SECONDS);</span><br><span class="line"> </span><br><span class="line">    ScheduledFuture&lt;?&gt; scheduledFuture &#x3D; executorService.schedule(() -&gt; &#123;</span><br><span class="line">        &#x2F;&#x2F; ...</span><br><span class="line">    &#125;, 1, TimeUnit.SECONDS);</span><br><span class="line"> </span><br><span class="line">    executorService.shutdown();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><em>ScheduledExecutorService</em> can also schedule the task <strong>after some given fixed delay</strong>:</p>
<p>也可预定任务在一定延后</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">executorService.scheduleAtFixedRate(() -&gt; &#123;</span><br><span class="line">    &#x2F;&#x2F; ...</span><br><span class="line">&#125;, 1, 10, TimeUnit.SECONDS);</span><br><span class="line"> </span><br><span class="line">executorService.scheduleWithFixedDelay(() -&gt; &#123;</span><br><span class="line">    &#x2F;&#x2F; ...</span><br><span class="line">&#125;, 1, 10, TimeUnit.SECONDS);</span><br></pre></td></tr></table></figure>

<p>Here, the <strong><em>scheduleAtFixedRate( Runnable command, long initialDelay（初始延迟）, long period（时间）, TimeUnit unit )\</em></strong> method creates and executes a periodic action that is invoked firstly after the provided initial delay, and subsequently with the given period until the service instance shutdowns.</p>
<p>创建并执行一个周期性操作，该操作将在提供的初始延迟后首先调用，然后以给定的周期调用，直到服务实例关闭为止。</p>
<p>The <strong><em>scheduleWithFixedDelay( Runnable command, long initialDelay, long delay, TimeUnit unit )\</em></strong> method creates and executes a periodic action that is invoked firstly after the provided initial delay, and repeatedly with the given delay between the termination of the executing one and the invocation of the next one.</p>
<p>创建并执行一个周期性操作，该周期性操作会在提供的初始延迟后首先调用，并在执行的终止与下一个调用的调用之间以给定的延迟重复进行。</p>
</blockquote>
<h3 id="Future（）"><a href="#Future（）" class="headerlink" title="Future（）"></a><strong>Future（）</strong></h3><blockquote>
<p><strong><em>Future\</em> is used to represent the result of an asynchronous operation.</strong></p>
<p>用于表示异步操作的结果</p>
<p>It comes with methods for checking if the asynchronous operation is completed or not, getting the computed result, etc.</p>
<p>它包含检查异步操作是否完成，获取计算结果等的方法。</p>
<p>What’s more, the <em>cancel(boolean mayInterruptIfRunning)</em> API cancels the operation and releases the executing thread.</p>
<p>此外XXX API会取消操作并释放执行线程</p>
<p>If the value of <em>mayInterruptIfRunning</em> is true, the thread executing the task will be terminated instantly.</p>
<p>如果mayInterruptIfRunning的值为true，则执行任务的线程将立即终止。</p>
<p>Otherwise, in-progress tasks will be allowed to complete.</p>
<p>否则，将允许正在进行的任务完成。</p>
<p>We can use below code snippet to create a future instance:</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">public void invoke() &#123;</span><br><span class="line"> ExecutorService executorService &#x3D; Executors.newFixedThreadPool(10);</span><br><span class="line"></span><br><span class="line"> Future&lt;String&gt; future &#x3D; executorService.submit(() -&gt; &#123;</span><br><span class="line">     &#x2F;&#x2F; ...</span><br><span class="line">     Thread.sleep(10000l);</span><br><span class="line">     return &quot;Hello world&quot;;</span><br><span class="line"> &#125;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>We can use following code snippet to check if the future result is ready and fetch the data if the computation is done:</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">if (future.isDone() &amp;&amp; !future.isCancelled()) &#123;</span><br><span class="line"> try &#123;</span><br><span class="line">     str &#x3D; future.get();</span><br><span class="line"> &#125; catch (InterruptedException | ExecutionException e) &#123;</span><br><span class="line">     e.printStackTrace();</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>We can also specify a timeout for a given operation. If the task takes more than this time, a <em>TimeoutException</em> is thrown:</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">try &#123;</span><br><span class="line"> future.get(10, TimeUnit.SECONDS);</span><br><span class="line">&#125; catch (InterruptedException | ExecutionException | TimeoutException e) &#123;</span><br><span class="line"> e.printStackTrace();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="CountDownLatch（闭锁）"><a href="#CountDownLatch（闭锁）" class="headerlink" title="CountDownLatch（闭锁）"></a><strong>CountDownLatch（闭锁）</strong></h3><blockquote>
<p><em>CountDownLatch</em> (introduced in <em>JDK 5</em>) is a utility class which blocks a set of threads until some operation completes.</p>
<p>一个实用程序类，它将阻止一组线程，直到完成某些操作为止。</p>
<p>CountDownLatch用一个计数器（整数类型）初始化；随着从属线程完成执行，此计数器递减。</p>
<p>A <em>CountDownLatch</em> is initialized with a <em>counter(Integer</em> type);</p>
<p>用一个计数器初始化</p>
<p>this counter decrements as the dependent threads complete execution.</p>
<p>这个计数器随着从属线程完成执行而递减</p>
<p>But once the counter reaches zero, other threads get released.</p>
<p>但是一旦计数器达到零，其他线程就会被释放。</p>
<p>You can learn more about <em>CountDownLatch</em> <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-countdown-latch">here</a>.</p>
<p>您可以在此处了解有关CountDownLatch的更多信息。</p>
</blockquote>
<h3 id="CyclicBarrier栅栏"><a href="#CyclicBarrier栅栏" class="headerlink" title="CyclicBarrier栅栏"></a><strong>CyclicBarrier栅栏</strong></h3><blockquote>
<p><em>CyclicBarrier</em> works almost the same as <em>CountDownLatch</em> except that we can reuse it.</p>
<p>XX的功能几乎和XXX相同，除了我们可以重复使用他</p>
<p>Unlike <em>CountDownLatch</em>, it allows multiple threads to wait for each other using <em>await()</em> method(known as barrier condition) before invoking the final task.</p>
<p>不像XXX 在调用最终的任务之前，它允许多个线程使用await（）方法互相等待（称为屏障条件）</p>
<p>栅栏类似于闭锁，它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于，所有的线程必须同时到达栅栏位置，才能继续执行。闭锁用于等待事件，而栅栏用于等待其他线程。</p>
<p>We need to create a <em>Runnable</em> task instance to initiate the barrier condition:</p>
<p>启动屏障时我们需要创建一个XXX任务实例</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">public class Task implements Runnable &#123;</span><br><span class="line"></span><br><span class="line"> private CyclicBarrier barrier;</span><br><span class="line"></span><br><span class="line"> public Task(CyclicBarrier barrier) &#123;</span><br><span class="line">     this.barrier &#x3D; barrier;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public void run() &#123;</span><br><span class="line">     try &#123;</span><br><span class="line">         LOG.info(Thread.currentThread().getName() + </span><br><span class="line">           &quot; is waiting&quot;);</span><br><span class="line">         barrier.await();</span><br><span class="line">         LOG.info(Thread.currentThread().getName() + </span><br><span class="line">           &quot; is released&quot;);</span><br><span class="line">     &#125; catch (InterruptedException | BrokenBarrierException e) &#123;</span><br><span class="line">         e.printStackTrace();</span><br><span class="line">     &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Now we can invoke some threads to race for the barrier condition:</p>
<p>现在我们可以调用一些线程来竞争屏障条件：</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">public void start() &#123;</span><br><span class="line"></span><br><span class="line"> CyclicBarrier cyclicBarrier &#x3D; new CyclicBarrier(3, () -&gt; &#123;</span><br><span class="line">     &#x2F;&#x2F; ...</span><br><span class="line">     LOG.info(&quot;All previous tasks are completed&quot;);</span><br><span class="line"> &#125;);</span><br><span class="line"></span><br><span class="line"> Thread t1 &#x3D; new Thread(new Task(cyclicBarrier), &quot;T1&quot;); </span><br><span class="line"> Thread t2 &#x3D; new Thread(new Task(cyclicBarrier), &quot;T2&quot;); </span><br><span class="line"> Thread t3 &#x3D; new Thread(new Task(cyclicBarrier), &quot;T3&quot;); </span><br><span class="line"></span><br><span class="line"> if (!cyclicBarrier.isBroken()) &#123; </span><br><span class="line">     t1.start(); </span><br><span class="line">     t2.start(); </span><br><span class="line">     t3.start(); </span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Here, the <em>isBroken()</em> method checks if any of the threads got interrupted during the execution time. We should always perform this check before performing the actual process.</p>
<p>isBroken（）方法检查在执行期间是否有任何线程被中断。在执行实际过程之前，我们应始终执行此检查。</p>
</blockquote>
<h3 id="Semaphore（多元信号量）"><a href="#Semaphore（多元信号量）" class="headerlink" title="Semaphore（多元信号量）"></a><strong>Semaphore（多元信号量）</strong></h3><blockquote>
<p>tips：Binary Semaphore（二元信号量） 是最简单的一种锁</p>
<p>The <em>Semaphore</em> is used for blocking thread level access to some part of the physical or logical resource. A semaphore contains a set of permits; whenever a thread tries to enter the critical section, it needs to check the semaphore if a permit is available or not.</p>
<p>信号量用于阻止线程级别访问物理或逻辑资源的某些部分。信号量包含了一组许可证；每当线程尝试进入关键部分时，它都需要检查信号量，以查看是否有许可。</p>
<p><strong>If a permit is not available (via *tryAcquire()*), the thread is not allowed to jump into the critical section; however, if the permit is available the access is granted, and the permit counter decreases.</strong></p>
<p>如果没有许可证（通过tryAcquire（）），则不允许该线程跳转到关键部分；但是，如果许可证可用，则授予访问权限，并且许可证计数器减少。</p>
<p>Once the executing thread releases the critical section, again the permit counter increases (done by <em>release()</em> method).</p>
<p>一旦执行线程释放了关键部分，许可计数器就会再次增加（由release（）方法完成）</p>
<p>We can specify a timeout for acquiring access by using the <em>tryAcquire(long timeout, TimeUnit unit)</em> method.</p>
<p>我们可以使用tryAcquire（long timeout，TimeUnit unit）方法去指定用于获取访问权限的超时。</p>
<p><strong>We can also check the number of available permits or the number of threads waiting to acquire the semaphore.</strong></p>
<p>我们还可以检查可用许可数或等待获取信号量的线程数。</p>
<p>ex: Semaphore是一种基于计数的信号量。它可以设定一个阈值，基于此，多个线程竞争获取许可信号，做完自己的申请后归还，超过阈值后，线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池，资源池之类的，比如数据库连接池，我们也可以创建计数为1的Semaphore，将其作为一种类似互斥锁的机制，这也叫二元信号量，表示两种互斥状态</p>
<p>Following code snippet can be used to implement a semaphore:</p>
<p>下面的代码块可以用来实现或继承semaphore</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">static Semaphore semaphore &#x3D; new Semaphore(10);</span><br><span class="line"> </span><br><span class="line">public void execute() throws InterruptedException &#123;</span><br><span class="line"> </span><br><span class="line">    LOG.info(&quot;Available permit : &quot; + semaphore.availablePermits());</span><br><span class="line">    LOG.info(&quot;Number of threads waiting to acquire: &quot; + </span><br><span class="line">      semaphore.getQueueLength());</span><br><span class="line"> </span><br><span class="line">    if (semaphore.tryAcquire()) &#123;</span><br><span class="line">        try &#123;</span><br><span class="line">            &#x2F;&#x2F; ...</span><br><span class="line">        &#125;</span><br><span class="line">        finally &#123;</span><br><span class="line">            semaphore.release();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>We can implement a <em>Mutex</em> like data-structure using <em>Semaphore</em>. More details on this<a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-semaphore"> can be found here.</a>我们可以使用信号量实现类似Mutex的数据结构</p>
</blockquote>
<h3 id="ThreadFactory（线程工厂）"><a href="#ThreadFactory（线程工厂）" class="headerlink" title="ThreadFactory（线程工厂）"></a><strong>ThreadFactory（线程工厂）</strong></h3><blockquote>
<p>As the name suggests（顾名思义）, <em>ThreadFactory</em> acts as a thread (non-existing) pool which creates a new thread on demand.</p>
<p>顾名思义，ThreadFactory充当线程（不存在）的池，可根据需要创建新线程。</p>
<p>It eliminates the need of a lot of boilerplate coding for implementing efficient thread creation mechanisms.</p>
<p>它消除了用于实现有效的线程创建机制的大量样板代码的需求。</p>
<p>We can define（定义） a <em>ThreadFactory</em>:</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">public class BaeldungThreadFactory implements ThreadFactory &#123;</span><br><span class="line">    private int threadId;</span><br><span class="line">    private String name;</span><br><span class="line"> </span><br><span class="line">    public BaeldungThreadFactory(String name) &#123;</span><br><span class="line">        threadId &#x3D; 1;</span><br><span class="line">        this.name &#x3D; name;</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">    @Override</span><br><span class="line">    public Thread newThread(Runnable r) &#123;</span><br><span class="line">        Thread t &#x3D; new Thread(r, name + &quot;-Thread_&quot; + threadId);</span><br><span class="line">        LOG.info(&quot;created new thread with id : &quot; + threadId +</span><br><span class="line">            &quot; and name : &quot; + t.getName());</span><br><span class="line">        threadId++;</span><br><span class="line">        return t;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>We can use this <em>newThread(Runnable r)</em> method to create a new thread at runtime:</p>
<p>在程序运行时我们可以使用XXX去创建一个新的线程</p>
<p>Java</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">BaeldungThreadFactory factory &#x3D; new BaeldungThreadFactory( </span><br><span class="line">    &quot;BaeldungThreadFactory&quot;);</span><br><span class="line">for (int i &#x3D; 0; i &lt; 10; i++) &#123; </span><br><span class="line">    Thread t &#x3D; factory.newThread(new Task());</span><br><span class="line">    t.start(); </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="BlockingQueue（阻塞队列）"><a href="#BlockingQueue（阻塞队列）" class="headerlink" title="BlockingQueue（阻塞队列）"></a>BlockingQueue（阻塞队列）</h3><blockquote>
<p>In asynchronous programming, one of the most common integration patterns is the <a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem">producer-consumer pattern</a>.</p>
<p>The <em>java.util.concurrent</em> package comes with a data-structure know as <em>BlockingQueue</em> – which can be very useful in these async scenarios.</p>
<p>More information and a working example on this is available <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-blocking-queue">here</a>.</p>
<p>在异步编程中，最常见的集成模式之一是生产者－消费者模式。</p>
<p>java.util.concurrent包附带一个称为BlockingQueue的数据结构–在这些异步情况下非常有用。 此处提供了更多信息和工作示例。</p>
</blockquote>
<h3 id="DelayQueue"><a href="#DelayQueue" class="headerlink" title="DelayQueue"></a><strong>DelayQueue</strong></h3><blockquote>
<p><em>DelayQueue</em> is an infinite-size blocking queue of elements where an element can only be pulled if it’s expiration time (known as user defined delay) is completed. Hence, the topmost element (<em>head</em>) will have the most amount delay and it will be polled last.</p>
<p>More information and a working example on this is available <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-delay-queue">here</a>.</p>
<p>DelayQueue是元素的无限大小的阻塞队列，在该队列中，只有在元素的到期时间（称为用户定义的延迟）完成后才能将其拉出。因此，最上面的元素（头）将具有最大的延迟量，并且将在最后轮询。</p>
</blockquote>
<h3 id="Locks"><a href="#Locks" class="headerlink" title="Locks"></a><strong>Locks</strong></h3><blockquote>
<p>Not surprisingly, <em>Lock</em> is a utility for blocking other threads from accessing a certain segment of code, apart from the thread that’s executing it currently.</p>
<p>The main difference between a Lock and a Synchronized block is that synchronized block is fully contained in a method; however, we can have Lock API’s lock() and unlock() operation in separate methods.</p>
<p>More information and a working example on this is available <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-concurrent-locks">here</a>.</p>
<p>毫不奇怪，Lock是一种实用程序，用于阻止其他线程访问代码的特定部分（当前正在执行该代码的线程除外）。 Lock和Synchronized块之间的主要区别在于，同步块完全包含在方法中。但是，我们可以在单独的方法中使用Lock API的lock（）和unlock（）操作。</p>
</blockquote>
<h3 id="Phaser"><a href="#Phaser" class="headerlink" title="Phaser"></a><strong>Phaser</strong></h3><blockquote>
<p><em>Phaser</em> is a more flexible solution than <em>CyclicBarrier</em> and <em>CountDownLatch</em> – used to act as a reusable barrier on which the dynamic number of threads need to wait before continuing execution. We can coordinate multiple phases of execution, reusing a <em>Phaser</em> instance for each program phase.</p>
<p>More information and a working example on this is available <a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.baeldung.com/java-phaser">here</a>.</p>
<p>与CyclicBarrier和CountDownLatch相比，Phaser是一种更加灵活的解决方案– CyclicBarrier和CountDownLatch用作可重复使用的屏障，动态数量的线程需要等待该屏障才能继续执行。我们可以协调执行的多个阶段，为每个程序阶段重用一个Phaser实例。</p>
</blockquote>
<h1 id="Conclusion（结论）"><a href="#Conclusion（结论）" class="headerlink" title="Conclusion（结论）"></a><strong>Conclusion（结论）</strong></h1><p>In this high-level, overview article, we’ve focused on the different utilities available of <em>java.util.concurrent</em> package.</p>
<p>As always, the full source code is available <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-concurrency-basic">over on GitHub</a>.</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined" rel="external nofollow noreferrer">伊长空</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://yichangkong.gitee.io/2020/05/29/Concurrent%20Overview/">https://yichangkong.gitee.io/2020/05/29/Concurrent%20Overview/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="external nofollow noreferrer" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://yichangkong.gitee.io" target="_blank">YiChangKong For Blog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E6%8A%80%E6%9C%AF%E6%A6%82%E8%BF%B0/">技术概述</a></div><div class="post_share"><div class="social-share" data-image="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2020/07/04/Why%20choose%20Flutter/"><img class="prev-cover" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="onerror=null;src='/img/404.jpg'"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Why choose Flutter</div></div></a></div><div class="next-post pull-right"><a href="/2020/05/26/Volatile%20Keyword/"><img class="next-cover" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="onerror=null;src='/img/404.jpg'"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">Volatile Keyword</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span> 相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2020/05/22/BinaryTree Overview/" title="BinaryTree Overview"><img class="cover" src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20201123185203.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-05-22</div><div class="title">BinaryTree Overview</div></div></a></div><div><a href="/2020/11/04/Gang of Four Design Patterns /" title="Gang of Four Design Patterns"><img class="cover" src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20201123195941.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-11-04</div><div class="title">Gang of Four Design Patterns</div></div></a></div><div><a href="/2020/11/04/Intrinsic Locks and Synchronization/" title="Intrinsic Locks and Synchronization"><img class="cover" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-11-04</div><div class="title">Intrinsic Locks and Synchronization</div></div></a></div><div><a href="/2020/05/14/JVM Overview/" title="JVM Overview"><img class="cover" src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20200511210319.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-05-14</div><div class="title">JVM Overview</div></div></a></div><div><a href="/2020/07/14/Lambda Expressions in Java 8/" title="Lambda Expressions in Java 8"><img class="cover" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-07-14</div><div class="title">Lambda Expressions in Java 8</div></div></a></div><div><a href="/2020/05/12/Mycat Overview/" title="Mycat Overview"><img class="cover" src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20201123150010.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-05-12</div><div class="title">Mycat Overview</div></div></a></div></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside_content" id="aside_content"><div class="card-widget card-info"><div class="card-content"><div class="card-info-avatar is-center"><img class="avatar-img" src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20200417183933.png" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/><div class="author-info__name">伊长空</div><div class="author-info__description">空气越稀薄 、风景越广阔</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">45</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">9</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">45</div></a></div></div><a class="button--animated" id="card-info-btn" target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/CodeSnakes"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/yichangkong" rel="external nofollow noreferrer" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:changkongyi@gmail.com" rel="external nofollow noreferrer" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div></div><div class="card-widget card-announcement"><div class="card-content"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">繁华落尽一场空 ：风往尘香花已尽 <br> 		<div class="is-center"> 欢迎访问 <br> <a class="bookmark button--primary" id="bookmark-it" href="https://jq.qq.com/?_wv=1027&amp;k=rCby8DjL" rel="external nofollow noreferrer" title="" target="_self"><i aria-hidden="true"> </i><span>Join QQ Group 👍</span></a></div></div></div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="card-content"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%8F%90%E5%89%8D%E8%AF%9D%EF%BC%9A"><span class="toc-number">1.</span> <span class="toc-text">提前话：</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Overview-of-the-java-util-concurrent%EF%BC%88%E6%A6%82%E8%BF%B0%EF%BC%89"><span class="toc-number">2.</span> <span class="toc-text">Overview of the java.util.concurrent（概述）</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Main-Components%EF%BC%88%E4%B8%BB%E8%A6%81%E6%9E%84%E6%88%90%EF%BC%89"><span class="toc-number">2.1.</span> <span class="toc-text">Main Components（主要构成）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Executor-%E6%89%A7%E8%A1%8C%E5%99%A8"><span class="toc-number">2.1.1.</span> <span class="toc-text">Executor(执行器)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ExecutorService%EF%BC%88%E6%89%A7%E8%A1%8C%E5%99%A8%E6%9C%8D%E5%8A%A1%EF%BC%89"><span class="toc-number">2.1.2.</span> <span class="toc-text">ExecutorService（执行器服务）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ScheduledExecutorService%EF%BC%88%E5%AE%9A%E6%97%B6%E8%B0%83%E5%BA%A6%E6%9C%BA%E5%88%B6%EF%BC%89"><span class="toc-number">2.1.3.</span> <span class="toc-text">ScheduledExecutorService（定时调度机制）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Future%EF%BC%88%EF%BC%89"><span class="toc-number">2.1.4.</span> <span class="toc-text">Future（）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#CountDownLatch%EF%BC%88%E9%97%AD%E9%94%81%EF%BC%89"><span class="toc-number">2.1.5.</span> <span class="toc-text">CountDownLatch（闭锁）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#CyclicBarrier%E6%A0%85%E6%A0%8F"><span class="toc-number">2.1.6.</span> <span class="toc-text">CyclicBarrier栅栏</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Semaphore%EF%BC%88%E5%A4%9A%E5%85%83%E4%BF%A1%E5%8F%B7%E9%87%8F%EF%BC%89"><span class="toc-number">2.1.7.</span> <span class="toc-text">Semaphore（多元信号量）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ThreadFactory%EF%BC%88%E7%BA%BF%E7%A8%8B%E5%B7%A5%E5%8E%82%EF%BC%89"><span class="toc-number">2.1.8.</span> <span class="toc-text">ThreadFactory（线程工厂）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#BlockingQueue%EF%BC%88%E9%98%BB%E5%A1%9E%E9%98%9F%E5%88%97%EF%BC%89"><span class="toc-number">2.1.9.</span> <span class="toc-text">BlockingQueue（阻塞队列）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DelayQueue"><span class="toc-number">2.1.10.</span> <span class="toc-text">DelayQueue</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Locks"><span class="toc-number">2.1.11.</span> <span class="toc-text">Locks</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Phaser"><span class="toc-number">2.1.12.</span> <span class="toc-text">Phaser</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Conclusion%EF%BC%88%E7%BB%93%E8%AE%BA%EF%BC%89"><span class="toc-number">3.</span> <span class="toc-text">Conclusion（结论）</span></a></li></ol></div></div></div><div class="card-widget card-recent-post"><div class="card-content"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2022/04/28/JOIN-Clause/" title="JOIN_Clause"><img src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="JOIN_Clause"/></a><div class="content"><a class="title" href="/2022/04/28/JOIN-Clause/" title="JOIN_Clause">JOIN_Clause</a><time datetime="2022-04-28T15:42:04.000Z" title="发表于 2022-04-28 23:42:04">2022-04-28</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2022/03/24/Vim%E9%94%AE%E4%BD%8D%E5%9B%BE/" title="Vim键位图"><img src="https://gitee.com/yichangkong/FigureBed/raw/master/img/vi-vim-cheat-sheet-sch.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Vim键位图"/></a><div class="content"><a class="title" href="/2022/03/24/Vim%E9%94%AE%E4%BD%8D%E5%9B%BE/" title="Vim键位图">Vim键位图</a><time datetime="2022-03-24T03:32:15.000Z" title="发表于 2022-03-24 11:32:15">2022-03-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/01/12/requirejs%20Overview/" title="RequireJs Overview"><img src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="RequireJs Overview"/></a><div class="content"><a class="title" href="/2021/01/12/requirejs%20Overview/" title="RequireJs Overview">RequireJs Overview</a><time datetime="2021-01-12T02:43:34.000Z" title="发表于 2021-01-12 10:43:34">2021-01-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2020/12/12/SSM%E6%9E%B6%E6%9E%84%E4%B8%8B%E7%9A%84Cors%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" title="SSM架构下的Cors跨域问题"><img src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20201213132701.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="SSM架构下的Cors跨域问题"/></a><div class="content"><a class="title" href="/2020/12/12/SSM%E6%9E%B6%E6%9E%84%E4%B8%8B%E7%9A%84Cors%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/" title="SSM架构下的Cors跨域问题">SSM架构下的Cors跨域问题</a><time datetime="2020-12-12T13:13:28.000Z" title="发表于 2020-12-12 21:13:28">2020-12-12</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2020/11/25/DataTable/" title="DataTable"><img src="https://gitee.com/yichangkong/FigureBed/raw/master/img/20201125100521.png" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="DataTable"/></a><div class="content"><a class="title" href="/2020/11/25/DataTable/" title="DataTable">DataTable</a><time datetime="2020-11-25T01:45:41.000Z" title="发表于 2020-11-25 09:45:41">2020-11-25</time></div></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2022 By 伊长空</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener external nofollow noreferrer" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div><script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js"></script><div class="js-pjax"><script>function loadValine () {
  function initValine () {
    let initData = {
      el: '#vcomment',
      appId: 'xuXblFdHlR0fcnQsdkLwkqvG-gzGzoHsz',
      appKey: 'ac3XS1leXcL95PWUhYV6gx0E',
      placeholder: 'Please leave your footprints',
      avatar: 'retro',
      meta: 'nick,mail'.split(','),
      pageSize: '10',
      lang: 'en',
      recordIP: false,
      serverURLs: '',
      emojiCDN: 'https://img.t.sinajs.cn/t4/appstyle/expression/ext/normal/',
      emojiMaps: {"tv_doge":"6ea59c827c414b4a2955fe79e0f6fd3dcd515e24.png","tv_亲亲":"a8111ad55953ef5e3be3327ef94eb4a39d535d06.png","tv_偷笑":"bb690d4107620f1c15cff29509db529a73aee261.png","tv_再见":"180129b8ea851044ce71caf55cc8ce44bd4a4fc8.png","tv_冷漠":"b9cbc755c2b3ee43be07ca13de84e5b699a3f101.png","tv_发怒":"34ba3cd204d5b05fec70ce08fa9fa0dd612409ff.png","tv_发财":"34db290afd2963723c6eb3c4560667db7253a21a.png","tv_可爱":"9e55fd9b500ac4b96613539f1ce2f9499e314ed9.png","tv_吐血":"09dd16a7aa59b77baa1155d47484409624470c77.png","tv_呆":"fe1179ebaa191569b0d31cecafe7a2cd1c951c9d.png","tv_呕吐":"9f996894a39e282ccf5e66856af49483f81870f3.png","tv_困":"241ee304e44c0af029adceb294399391e4737ef2.png","tv_坏笑":"1f0b87f731a671079842116e0991c91c2c88645a.png","tv_大佬":"093c1e2c490161aca397afc45573c877cdead616.png","tv_大哭":"23269aeb35f99daee28dda129676f6e9ea87934f.png","tv_委屈":"d04dba7b5465779e9755d2ab6f0a897b9b33bb77.png","tv_害羞":"a37683fb5642fa3ddfc7f4e5525fd13e42a2bdb1.png","tv_尴尬":"7cfa62dafc59798a3d3fb262d421eeeff166cfa4.png","tv_微笑":"70dc5c7b56f93eb61bddba11e28fb1d18fddcd4c.png","tv_思考":"90cf159733e558137ed20aa04d09964436f618a1.png","tv_惊吓":"0d15c7e2ee58e935adc6a7193ee042388adc22af.png"},
      enableQQ: false,
      path: window.location.pathname,
    }

    if (true) { 
      initData.requiredFields= ('nick'.split(','))
    }
    
    if (false) {
      const otherData = false
      initData = Object.assign({}, initData, otherData)
    }
    
    const valine = new Valine(initData)
  }

  if (typeof Valine === 'function') initValine() 
  else $.getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js', initValine)
}

if ('Valine' === 'Valine' || !false) {
  if (false) btf.loadComment(document.querySelector('#vcomment'),loadValine)
  else setTimeout(() => loadValine(), 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><script src="https://cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script></div></body></html>